package org.jetlinks.community.mstn.web;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.hswebframework.ezorm.core.param.Sort;
import org.hswebframework.ezorm.core.param.Term;
import org.hswebframework.web.api.crud.entity.PagerResult;
import org.hswebframework.web.api.crud.entity.QueryParamEntity;
import org.hswebframework.web.authorization.annotation.*;
import org.hswebframework.web.id.IDGenerator;
import org.hswebframework.web.system.authorization.api.entity.DimensionUserEntity;
import org.hswebframework.web.system.authorization.defaults.service.DefaultDimensionUserService;
import org.jetlinks.community.auth.entity.RoleEntity;
import org.jetlinks.community.auth.enums.RoleState;
import org.jetlinks.community.auth.enums.RoleType;
import org.jetlinks.community.auth.service.RoleService;
import org.jetlinks.community.mstn.utils.uuid.IdUtils;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.List;


@RestController
@RequestMapping({"/mstn/tenantPackage","/mstn/tenant-package"})
@Authorize
@Resource(id = "tenant-package", name = "租户套餐", group = "mstn")
@Tag(name = "租户套餐")
@AllArgsConstructor
public class TenantPackageController {

    private final RoleService service;

    private final DefaultDimensionUserService dimensionUserService;
    @PostMapping("/list")
    public Mono<PagerResult<RoleEntity>> queryPackagesList(@RequestBody Mono<QueryParamEntity> param) {

        return service.queryPager(
                param.doOnNext(
                queryParamEntity -> {
                    List<Term> terms = queryParamEntity.getTerms();
                    Term roleTypeTerm = new Term();
                    roleTypeTerm.setColumn("roleType");
                    roleTypeTerm.setValue(RoleType.tenant);
                    terms.add(roleTypeTerm);
                    List<Sort> sorts = new ArrayList<>();
                    sorts.add(new Sort("createTime").desc());
                    sorts.add(new Sort("id").desc());
                    queryParamEntity.setSorts(sorts);
                }
        ));
    }

    @PostMapping("/no-paging")
    public Flux<RoleEntity> noPaging(@RequestBody Mono<QueryParamEntity> param) {

        return service.query(
            param.doOnNext(
                queryParamEntity -> {
                    List<Term> terms = queryParamEntity.getTerms();
                    Term roleTypeTerm = new Term();
                    roleTypeTerm.setColumn("roleType");
                    roleTypeTerm.setValue(RoleType.tenant);
                    terms.add(roleTypeTerm);
                    Term statusTerm = new Term();
                    statusTerm.setColumn("state");
                    statusTerm.setValue(RoleState.enabled.getValue());
                    terms.add(statusTerm);
                    List<Sort> sorts = new ArrayList<>();
                    sorts.add(new Sort("createTime").desc());
                    sorts.add(new Sort("id").desc());
                    queryParamEntity.setSorts(sorts);
                }
            ));
    }
    @PostMapping
    @CreateAction
    @Operation(summary = "创建租户套餐")
    public Mono<RoleEntity> create(@RequestBody RoleEntity roleEntity) {
        roleEntity.setId(IdUtils.fastUUID());
        roleEntity.setRoleType(RoleType.tenant);

        return service.insert(roleEntity).flatMap(count -> service.findById(roleEntity.getId()));
    }

    @PutMapping("/{id}")
    @SaveAction
    @Operation(summary = "修改租户套餐")
    public Mono<Integer> save(@PathVariable String id, @RequestBody RoleEntity roleEntity) {
        roleEntity.setRoleType(RoleType.tenant);
        roleEntity.setState(null);
        return service.updateById(id, roleEntity);
    }

    @PutMapping("/{id}/enabled")
    @SaveAction
    @Operation(summary = "启用租户套餐")
    public Mono<Integer> enabled(@PathVariable String id) {
        RoleEntity roleEntity = new RoleEntity();
        roleEntity.setState(RoleState.enabled);
        return service.updateById(id, roleEntity);
    }

    @PutMapping("/{id}/disabled")
    @SaveAction
    @Operation(summary = "禁用租户套餐")
    public Mono<Integer> disabled(@PathVariable String id) {

        //校验是否有正在使用的租户
        return dimensionUserService.createQuery()
            .where(DimensionUserEntity::getDimensionTypeId,"role")
            .and(DimensionUserEntity::getDimensionId, id)
            .fetch()
            .collectList()
            .flatMap( list -> {
                if (!list.isEmpty()) {
                    return Mono.just(0);
                } else {
                    RoleEntity roleEntity = new RoleEntity();
                    roleEntity.setState(RoleState.disabled);
                    return service.updateById(id, roleEntity);
                }
            });
    }

    @DeleteMapping("/{id}")
    @DeleteAction
    @Operation(summary = "删除租户套餐")
    public Mono<Integer> delete(@PathVariable String id) {
        //校验是否有正在使用的租户
        return dimensionUserService.createQuery()
            .where(DimensionUserEntity::getDimensionTypeId,"role")
            .and(DimensionUserEntity::getDimensionId, id)
            .fetch()
            .collectList()
            .flatMap( list -> {
                if (!list.isEmpty()) {
                    return Mono.just(0);
                } else {
                    return service.deleteById(id);
                }
            });
    }


}